<template>
  <div class="ldm-tab">
    <TabScaffold :current="pagination.current" :pageSize="pagination.pageSize" :total="total"
      :pageCount="pageData.length" :checkAll="checkAll" @update:current="(v) => pagination.current = v"
      @update:pageSize="(v) => pagination.pageSize = v" @check-all="onCheckAll">
      <template #toolbar-left>
        <a-space>
          <a-button @click="onAdd">新增</a-button>
          <a-button :disabled="!selectedRowKeys.length" @click="onBatchDelete">批量删除</a-button>
          <a-button @click="openImportModal">导入</a-button>
          <a-button :loading="exporting" @click="openExportModal">导出</a-button>
        </a-space>
      </template>

      <template #toolbar-right>
        <a-input-search v-model:value="keyword" placeholder="输入搜索（名称/链接/备注）" enter-button="搜索" @search="onSearch"
          allow-clear style="width: 320px" />
      </template>

      <div class="table-scroll">
        <a-table :columns="columns" :data-source="pageData" row-key="id" :pagination="false"
          :row-selection="rowSelection" :loading="loading" bordered class="table" :customRow="onCustomRow">
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'link_name'">
              <span class="name-text">{{ record.link_name }}</span>
            </template>

            <template v-else-if="column.key === 'url'">
              <span class="url-text">{{ record.url }}</span>
            </template>

            <template v-else-if="column.key === 'status'">
              <span :class="['status', record.status === 'enabled' ? 'on' : 'off']">
                {{ record.status === 'enabled' ? '启用' : '停用' }}
              </span>
            </template>

            <template v-else-if="column.key === 'actions'">
              <span class="ops">
                <a @click="onEdit(record)">编辑</a>
                <span class="sep">|</span>
                <a @click="onDelete(record)" style="color: #ff4d4f;">删除</a>
                <span class="sep">|</span>
                <a v-if="record.status === 'enabled'" @click="onToggleStatus(record, 'disable')">停用</a>
                <span v-else class="disabled">停用</span>
                <span class="sep">|</span>
                <a v-if="record.status === 'disabled'" @click="onToggleStatus(record, 'enable')">启用</a>
                <span v-else class="disabled">启用</span>
              </span>
            </template>
          </template>
        </a-table>
      </div>
    </TabScaffold>

    <!-- 导入弹窗 -->
    <ImportModal v-model:modelValue="importVisible" title="链接删除管理导入" accept=".csv,text/csv,.json,application/json"
      tip="支持 CSV 或 JSON（UTF-8）。" @import="doImport" />

    <!-- 导出弹窗 -->
    <ExportModal v-model:modelValue="exportVisible" v-model:format="exportFormat" :loading="exporting" title="链接删除管理导出"
      @confirm="doExport" />
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive, ref, onMounted, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import type { Key } from "ant-design-vue/es/table/interface";
import type { TableRowSelection } from "ant-design-vue";
import { Modal, message } from "ant-design-vue";

import TabScaffold from "@/components/TabScaffold.vue";
import ImportModal from "@/components/ImportModal.vue";
import ExportModal from "@/components/ExportModal.vue";

import {
  getLinkDeletionList,
  deleteLinkDeletion,
  deleteLinkDeletions,
  enableLinkDeletion,
  disableLinkDeletion,
  type LinkDeletionItem,
  exportLinkDeletionsJSON,
  importLinkDeletionsFile,
} from "@/api/modules/linkDeletion.api";

const router = useRouter();
const route = useRoute();

const TAB_KEY = "linkDeletionManagement";
const inMainTabs = computed(() => typeof route.query.tab === "string");

type Row = {
  id: string | number;
  link_name: string;
  url: string;
  memo?: string;
  status: "enabled" | "disabled";
  date_created?: string;
};

const pageData = ref<Row[]>([]);
const total = ref(0);
const loading = ref(false);

const keyword = ref("");
const pagination = reactive({ current: 1, pageSize: 10 });

const columns = [
  { title: "名称", dataIndex: "link_name", key: "link_name", width: 280, ellipsis: true },
  { title: "链接地址", dataIndex: "url", key: "url", ellipsis: true },
  { title: "备注", dataIndex: "memo", key: "memo", width: 240, ellipsis: true },
  { title: "状态", dataIndex: "status", key: "status", width: 120 },
  { title: "操作", key: "actions", width: 240 },
];

async function fetchList() {
  loading.value = true;
  try {
    const { list, total: t } = await getLinkDeletionList({
      page: pagination.current,
      pageSize: pagination.pageSize,
      keyword: keyword.value,
      sort: "id",
      excludeStatus: "archived",
    });

    if ((list?.length ?? 0) === 0 && pagination.current > 1) {
      pagination.current = pagination.current - 1;
      return;
    }

    pageData.value = (list || []).map((it: LinkDeletionItem) => ({
      id: it.id,
      link_name: it.link_name || "",
      url: it.url || "",
      memo: it.memo || "",
      status: it.status === "published" ? "enabled" : "disabled",
      date_created: it.date_created,
    }));
    total.value = t || 0;
    selectedRowKeys.value = [];
  } finally {
    loading.value = false;
  }
}

function onSearch() { pagination.current = 1; fetchList(); }
onMounted(fetchList);
watch(() => [pagination.current, pagination.pageSize], () => fetchList());

/* 选择 / 全选 */
const selectedRowKeys = ref<Key[]>([]);
const rowSelection = computed<TableRowSelection<Row>>(() => ({
  selectedRowKeys: selectedRowKeys.value,
  onChange: (keys: Key[]) => (selectedRowKeys.value = keys),
}));
const currentPageKeys = computed<Key[]>(() => pageData.value.map((r) => r.id));
const checkAll = computed(
  () => currentPageKeys.value.length > 0 && currentPageKeys.value.every((k) => selectedRowKeys.value.includes(k))
);
function onCheckAll(e: any) {
  const checked = e?.target?.checked;
  selectedRowKeys.value = checked
    ? Array.from(new Set([...selectedRowKeys.value, ...currentPageKeys.value]))
    : selectedRowKeys.value.filter((k) => !currentPageKeys.value.includes(k));
}

/* 跳转 */
function buildFromQuery() {
  return inMainTabs.value ? { backTo: "tab", from: route.path, tab: TAB_KEY } : {};
}
function onAdd() {
  router.push({ path: "/linkDeletionManagementPage", query: { ...buildFromQuery(), mode: "create" } });
}
function onEdit(row: Row) {
  router.push({
    path: "/linkDeletionManagementPage",
    query: { ...buildFromQuery(), mode: "edit", id: String(row.id), row: encodeURIComponent(JSON.stringify(row)) },
  });
}
function onNameClick(row: Row) {
  router.push({
    path: "/linkDeletionManagementInfo",
    query: { ...buildFromQuery(), id: String(row.id), row: encodeURIComponent(JSON.stringify(row)) },
  });
}

function onCustomRow(record: Row) {
  return {
    onClick: (e: MouseEvent) => {
      const target = e.target as HTMLElement;
      if (target && target.closest('.ops')) return;
      onNameClick(record);
    },
    style: { cursor: "pointer" },
  } as any;
}

/* 删除与启停 */
async function onBatchDelete() {
  if (!selectedRowKeys.value.length) return;
  Modal.confirm({
    title: "确认删除选中项？",
    okText: "删除",
    okType: "danger",
    cancelText: "取消",
    async onOk() {
      await deleteLinkDeletions(selectedRowKeys.value as Array<string | number>);
      message.success("删除成功");
      await fetchList();
    },
  });
}
function onDelete(row: Row) {
  Modal.confirm({
    title: "确认删除该记录？",
    content: `将删除：${row.link_name}`,
    okText: "删除",
    okType: "danger",
    cancelText: "取消",
    async onOk() {
      await deleteLinkDeletion(row.id);
      message.success("删除成功");
      await fetchList();
    },
  });
}
async function onToggleStatus(row: Row, action: "enable" | "disable") {
  const updated = action === "enable" ? await enableLinkDeletion(row.id) : await disableLinkDeletion(row.id);
  const backendStatus =
    (updated?.status as "published" | "draft" | undefined) ?? (action === "enable" ? "published" : "draft");
  row.status = backendStatus === "published" ? "enabled" : "disabled";
  message.success(backendStatus === "published" ? "已启用" : "已停用");
}

/* ===== 导出 ===== */
const exportVisible = ref(false);
const exportFormat = ref<"csv" | "json">("csv");
const exporting = ref(false);

function openExportModal() {
  exportFormat.value = "csv";
  exportVisible.value = true;
}

async function doExport() {
  if (exporting.value) return;
  exporting.value = true;
  try {
    const ids = (selectedRowKeys.value as Array<string | number>) ?? [];
    const hasSelection = ids.length > 0;

    const jsonBlob = await exportLinkDeletionsJSON({
      ids: hasSelection ? ids : undefined,
      keyword: hasSelection ? "" : keyword.value,
      excludeStatus: "archived",
    });

    const text = await blobToText(jsonBlob);
    const parsed = JSON.parse(text);
    const rows: any[] = Array.isArray(parsed) ? parsed : (parsed?.data ?? []);

    const plain = rows.map((r) => ({
      link_name: r?.link_name ?? "",
      url: r?.url ?? "",
      memo: r?.memo ?? "",
      status: r?.status ?? "",
    }));

    if (exportFormat.value === "json") {
      const out = new Blob([JSON.stringify(plain, null, 2)], { type: "application/json;charset=utf-8" });
      downloadFile(genName("json"), out);
      message.success("导出成功");
    } else {
      const header = "link_name,url,memo,status";
      const lines = plain.map((r) => [safeCsv(r.link_name), safeCsv(r.url), safeCsv(r.memo), safeCsv(r.status)].join(","));
      const csv = [header, ...lines].join("\n");
      const out = new Blob([csv], { type: "text/csv;charset=utf-8" });
      downloadFile(genName("csv"), out);
      message.success("导出成功");
    }

    exportVisible.value = false;
  } finally {
    exporting.value = false;
  }
}

function genName(ext: "csv" | "json") {
  const ts = new Date().toISOString().replace(/[-:T]/g, "").slice(0, 14);
  return `links_deletion_export_${ts}.${ext}`;
}
function downloadFile(filename: string, blob: Blob) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
}
function blobToText(b: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const fr = new FileReader();
    fr.onload = () => resolve(String(fr.result || ""));
    fr.onerror = reject;
    fr.readAsText(b);
  });
}
function safeCsv(s: string) {
  if (s == null) return "";
  const needQuote = /[",\n]/.test(s);
  const body = String(s).replace(/"/g, '""');
  return needQuote ? `"${body}"` : body;
}

/* ===== 导入===== */
const importVisible = ref(false);
const importing = ref(false);

function openImportModal() {
  importVisible.value = true;
}

async function doImport(file: File) {
  if (!file) {
    message.warning("请选择需要导入的文件");
    return;
  }
  const name = file.name.toLowerCase();
  if (!(name.endsWith(".csv") || name.endsWith(".json"))) {
    message.warning("请上传 .csv 或 .json 文件");
    return;
  }
  try {
    importing.value = true;
    const stat = await importLinkDeletionsFile(file);
    const inserted = Number(stat?.inserted ?? stat?.created ?? 0);
    const updated = Number(stat?.updated ?? 0);
    const skipped = Number(stat?.skipped ?? stat?.failed ?? 0);
    const total = stat?.total ?? (inserted + updated + skipped);
    const parts: string[] = [];
    if (typeof total !== "undefined") parts.push();
    if (inserted) parts.push(`新增 ${inserted}`);
    if (updated) parts.push(`更新 ${updated}`);
    if (skipped) parts.push(`跳过 ${skipped}`);
    message.success(parts.length ? `导入成功 ${parts.join("，")}` : "导入成功");

    await fetchList();
    importVisible.value = false;
  } catch (e: any) {
    const code =
      e?.response?.data?.errors?.[0]?.extensions?.code ||
      e?.data?.errors?.[0]?.extensions?.code ||
      e?.code;
    if (code === "RECORD_NOT_UNIQUE") {
      message.error("检测到重复的值");
    } else {
      message.error(e?.message || "导入失败");
    }
  } finally {
    importing.value = false;
  }
}
</script>

<style lang="less" scoped>
.ldm-tab {
  background: #fff;
  border-radius: 6px;
  min-width: 0;
}

.table-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

.table {
  :deep(.ant-table) {
    border: 1px solid #d9d9d9;
  }

  :deep(.ant-table-thead>tr>th) {
    background: #f4f8fd;
    color: #333;
    border-color: #d9d9d9;
    font-weight: 600;
    height: 40px;
    padding: 8px 12px;
  }

  :deep(.ant-table-tbody>tr>td) {
    border-color: #d9d9d9;
    height: 40px;
    padding: 8px 12px;
  }

  :deep(.name-link) {
    color: #1677ff;
    cursor: pointer;
    text-decoration: none;
  }

  :deep(.status.on) {
    color: #1f7a1f;
  }

  :deep(.status.off) {
    color: #999;
  }

  :deep(.ops .sep) {
    margin: 0 8px;
    color: #999;
  }

  :deep(.ops .disabled) {
    color: #c5c5c5 !important;
    cursor: not-allowed;
    pointer-events: none;
  }

  :deep(.name-text),
  :deep(.url-text) {
    color: #000;
  }
}
</style>
